<?php


namespace app\live\controller\v2;


use app\chat\LiveMessage;
use app\common\cachemodel\live\LiveAnchorInfo;
use app\common\cachemodel\live\LiveAward;
use app\common\cachemodel\live\LiveCoupon;
use app\common\cachemodel\live\LiveGoodsActivity;
use app\common\cachemodel\live\LiveMessage as LiveMessageModel;
use app\common\cachemodel\live\LiveMessageReport;
use app\common\cachemodel\live\LiveRecordingInfo;
use app\common\cachemodel\MallGoodsAttr;
use app\common\lib\Util;
use app\common\model\User;
use app\live\controller\LiveAuth;
use think\Cache;
use think\Db;
use think\Log;
use think\response\Json;
use XznsTools\cache\CacheManage;

class LiveInfo extends LiveAuth
{
    /**
     * 获取直播预告
     */
    public function getBroadcastPreview()
    {
        $broadcastPreviewInfo = Db::table('wechat_backup_07_18_14_43_00.live_broadcast_preview')->where('live_id', $this->liveInfo['live_id'])
            ->where('live_start_time', '>', $this->request->time())->order('id asc')
            ->field('broadcast_cover_img,broadcast_title,broadcast_content,live_start_time')->find();

        if ($broadcastPreviewInfo)
        {
            $resData = [
                'live_start_time' => date('Y-m-d H:i:s', $broadcastPreviewInfo['live_start_time'] ?? time()),
                'broadcast_title' => $broadcastPreviewInfo['broadcast_title'] ?? '',
                'broadcast_content' => $broadcastPreviewInfo['broadcast_content'] ?? '',
                'broadcast_cover_img' => $broadcastPreviewInfo['broadcast_cover_img'] ?? '',
                'btn_text' => '更新预告',
            ];
        } else
        {
            $resData = [
                'live_start_time' => '',
                'broadcast_title' => '',
                'broadcast_content' => '',
                'broadcast_cover_img' => '',
                'btn_text' => '添加预告',
            ];
        }

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 保存直播预告
     */
    public function saveBroadcastPreview()
    {
        $liveStartTime = input('live_start_time/s', '');
        $broadcast_title = input('broadcast_title/s', '');
        $broadcast_content = input('broadcast_content/s', '');
        $broadcast_cover_img = input('broadcast_cover_img/s', '');

        if (empty($liveStartTime))
        {
            return show(config('code.error'), '开播时间不能为空～');
        }

        if (empty($broadcast_title))
        {
            return show(config('code.error'), '直播标题不能为空～');
        }

        if (empty($broadcast_content))
        {
            return show(config('code.error'), '直播内容不能为空～');
        }

        if (mb_strlen($broadcast_title) > 12)
        {
            return show(config('code.error'), '直播标题不能不能超过12字！');
        }

        if (mb_strlen($broadcast_content) > 48)
        {
            return show(config('code.error'), '直播内容不能不能超过48字！');
        }

        if ($liveStartTime !== date('Y-m-d H:i', strtotime($liveStartTime)))
        {
            return show(config('code.error'), '开播时间错误');
        }

        $liveStartTime = strtotime($liveStartTime);

        try
        {
            $broadcastPreviewInfo = Db::table('wechat_backup_07_18_14_43_00.live_broadcast_preview')->where('live_id', $this->liveInfo['live_id'])
                ->where('live_start_time', '>', $this->request->time())->order('id asc')
                ->field('id,status')->find();

            $adminInfo = $this->getUserAuth();
            if ($broadcastPreviewInfo)
            {
                Db::table('wechat_backup_07_18_14_43_00.live_broadcast_preview')->where('id', $broadcastPreviewInfo['id'])->update([
                    'live_start_time' => $liveStartTime,
                    'broadcast_title' => $broadcast_title,
                    'broadcast_content' => $broadcast_content,
                    'broadcast_cover_img' => $broadcast_cover_img,
                    'update_time' => $this->request->time(),
                    'aid' => $adminInfo['aid'],
                    'admin_type' => $adminInfo['admin_type'],
                ]);
                CacheManage::getInstance()->setCacheConfig('live.broadcast_preview', $this->liveInfo['live_id'])->rmCache();
                if ((int)$broadcastPreviewInfo['status'] === 1)
                {
                    CacheManage::getInstance()->setCacheConfig('live.broadcast_preview', 0)->rmCache();
                }
            } else
            {
                Db::table('wechat_backup_07_18_14_43_00.live_broadcast_preview')->insert([
                    'live_id' => $this->liveInfo['live_id'],
                    'status' => 0,
                    'live_start_time' => $liveStartTime,
                    'broadcast_title' => $broadcast_title,
                    'broadcast_content' => $broadcast_content,
                    'broadcast_cover_img' => $broadcast_cover_img,
                    'create_time' => $this->request->time(),
                    'aid' => $adminInfo['aid'],
                    'admin_type' => $adminInfo['admin_type'],
                ]);

                CacheManage::getInstance()->setCacheConfig('live.broadcast_preview', $this->liveInfo['live_id'])->rmCache();
            }
        }
        catch (\Exception $e)
        {
            Log::write("发布/更新 直播预告失败;错误消息：{$e->getMessage()};FILE:{$e->getFile()};LINE:{$e->getLine()};", 'error');
            return show(config('code.error'), '服务异常；请稍后再试～');
        }
        return show(config('code.success'), '请求成功');
    }

    /**
     * 修改直播间信息
     * @return Json
     */
    public function alterRecordInfo()
    {
        $liveRecordId = input('live_record_id/d', 0);
        $title = input('live_title/s', '');
        $content = input('live_content/s', '');
        if (mb_strlen($title) > 12)
        {
            return json(['status' => 0, 'msg' => '标题最长15字']);
        }
        if (mb_strlen($content) > 48)
        {
            return json(['status' => 0, 'msg' => '内容最长50字']);
        }
        (new LiveRecordingInfo())->updateData($liveRecordId, ['title' => $title, 'content' => $content]);
        return json(['status' => 0, 'msg' => '修改成功']);
    }

    /**
     * 获取直播标题和直播内容接口
     * @return Json
     * @throws \Exception
     */
    public function getRecordInfo()
    {
        $liveRecordId = input('live_record_id/d', 0);

        $data = (new LiveRecordingInfo())->getInfoById($liveRecordId, ['title', 'content', 'live_id']);

        if ($data && (int)$data['live_id'] === $this->liveInfo['live_id'])
        {
            return show(config('code.success'), '请求成功', [
                'live_title' => $data['title'],
                'live_content' => $data['content']
            ]);
        } else
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
    }

    /**
     * 获取在线人数基数
     * @return Json
     * @throws \Exception
     */
    public function getOnlinePeopleNum()
    {
        // 获取最新的直播记录ID
        $newRecordId = (new LiveRecordingInfo())->getNewestRecord($this->liveInfo['live_id']);
        $recordInfo = (new LiveRecordingInfo())->getInfoById($newRecordId, ['status']);
        if (!$recordInfo['status'])
        {
            return show(config('code.error'), '直播不存在！');
        }
        $time = time();
        $peopleBaseNum = Cache::get($this->liveInfo['live_id'] . '-live_people_num-' . $newRecordId);
        $tips = '';
        if ($peopleBaseNum)
        {
            $peopleBaseNum = json_decode($peopleBaseNum, true);
            if ($peopleBaseNum['type'] === 1)
            {
                $timeEx = $time - $peopleBaseNum['timestamp'];
                $duration = $peopleBaseNum['duration'] * 60;
                if ($timeEx >= $duration)
                {
                    $startBaseNum = $peopleBaseNum['num'] + ($peopleBaseNum['start_base_num'] ?? 0);
                    $peopleBaseNum['duration'] = 0;
                } else
                {
                    $startBaseNum = (int)(($timeEx / $duration) * $peopleBaseNum['num']) + ($peopleBaseNum['start_base_num'] ?? 0);
                    $duration = ($peopleBaseNum['timestamp'] + $peopleBaseNum['duration'] * 60) - time();
                    $peopleBaseNum['duration'] = floor(($duration / 60) * 100) / 100;
                }
                $peopleBaseNum['valid_base_num'] = $startBaseNum;   //生效起始人数
                $peopleBaseNum['remain_num'] = $peopleBaseNum['num'] - ($peopleBaseNum['valid_base_num'] - $peopleBaseNum['start_base_num']);//剩余生效人数
            } else
            {
                $peopleBaseNum['valid_base_num'] = 0;
            }
            $tips = "提示：当前已增加（{$peopleBaseNum['valid_base_num']}）人,还有{$peopleBaseNum['duration']}分钟生效，待增加人数（{$peopleBaseNum['remain_num']}）人";
        }
        return show(config('code.success'), '获取成功！', ['tips' => $tips]);
    }

    /**
     * 设置在线人数基数
     * @return Json
     * @throws \Exception
     */
    public function setOnlinePeopleNum()
    {
        $base_type = input('base_type/d', 0);
        $start_base_num = input('start_base_num/d', 0);
        $num = input('num/d', 0);
        $duration = input('duration/d', 0);
        $time = time();
        if ($num <= 0)
        {
            return show(config('code.error'), '基数必须大于0！');
        }
        if ($base_type === 3 && $start_base_num <= 0)
        {
            return show(config('code.error'), '起始基数必须大于0！');
        }
        // 获取最新的直播记录ID
        $newRecordId = (new LiveRecordingInfo())->getNewestRecord($this->liveInfo['live_id']);
        $recordInfo = (new LiveRecordingInfo())->getInfoById($newRecordId, ['status']);
        if (!$recordInfo['status'])
        {
            return show(config('code.error'), '直播不存在！');
        }
        if ($base_type === 3)
        {
            $startBaseNum = $start_base_num;
        } elseif ($base_type === 2)
        {
            $startBaseNum = 0;
        } else
        {
            $oldData = Cache::get($this->liveInfo['live_id'] . '-live_people_num-' . $newRecordId, false);

            if ($oldData)
            {
                $oldData = json_decode($oldData, true);

                if ($oldData['type'] === 1)
                {
                    $timeEx = $time - $oldData['timestamp'];
                    $oldDuration = $oldData['duration'] * 60;
                    if ($timeEx >= $oldDuration)
                    {
                        $startBaseNum = $oldData['num'] + ($oldData['start_base_num'] ?? 0);
                    } else
                    {
                        $startBaseNum = (int)(($timeEx / $oldDuration) * $oldData['num']) + ($oldData['start_base_num'] ?? 0);
                    }
                } else
                {
                    $startBaseNum = 0;
                }
            } else
            {
                $startBaseNum = 0;
            }
        }

        $data = [
            'start_base_num' => $startBaseNum,
            'type' => 1,
            'num' => $num,
            'duration' => $duration,
            'timestamp' => $time,
        ];
        Cache::set($this->liveInfo['live_id'] . '-live_people_num-' . $newRecordId, json_encode($data, true), 86400);
        return show(config('code.success'), '设置成功！', []);

    }

    /**
     * 踢出直播间
     * @return Json
     * @throws \Exception
     */
    public function kickOutLive()
    {
        $messageId = input('message_id/d', 0);
        $liveRecordId = input('live_record_id/d', 0);
        $recordInfo = (new LiveRecordingInfo())->getInfoById($liveRecordId, ['status']);
        if (!$recordInfo['status'])
        {
            return show(config('code.error'), '直播不存在！');
        }
        $messageInfo = Db::table('`live_data`.live_message_' . $liveRecordId)
            ->where(['id' => $messageId, 'type' => 1])->field('uid')
            ->find();
        if ((!$messageInfo))
        {
            return show(config('code.error'), '用户不存在');
        }
        $res = Cache::get('out_user-' . $this->liveInfo['live_id'] . '-' . $liveRecordId . '-' . $messageInfo['uid']);
        if ($res)
        {
            return show(config('code.success'), '用户已被踢出直播间');
        }

        Cache::set('out_user-' . $this->liveInfo['live_id'] . '-' . $liveRecordId . '-' . $messageInfo['uid'], 1, 86400);

        //处理被举报弹幕数据
        (new LiveMessageReport())->where(['uid2' => $messageInfo['uid']])->update(['status' => 1]);

        //发送WS
        LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_UID, $this->liveInfo['live_id'], $messageInfo['uid']), LiveMessage::MSG_TYPE_ACTION_USER, 3);

        return show(config('code.success'), '踢出成功！');
    }

    /**
     * 发送弹幕或通知
     * @return Json
     * @throws \Exception
     */
    public function sendMsg()
    {
        $type = input('type/d', 0);
        $content = input('content/s', '');
        // 获取最新的直播记录ID
        $newRecordId = (new LiveRecordingInfo())->getNewestRecord($this->liveInfo['live_id']);
        $recordInfo = (new LiveRecordingInfo())->getInfoById($newRecordId, ['status']);
        if (!$recordInfo['status'])
        {
            return show(config('code.error'), '直播不存在！');
        }
        if ($type === 1)
        {
            LiveMessage::sendMsg(['type' => 'all', 'live_id' => $this->liveInfo['live_id'], 'id' => $this->liveInfo['live_id']], LiveMessage::MSG_TYPE_POP_HEADER, [
                'title' => $content,
                'target' => 'local',
                'link' => '',
                'continue_second' => 10,
            ]);
        } else
        {
            $adminInfo = $this->getUserAuth();
            //  弹幕数新增 弹幕入库
            $insertData = [
                'uid' => $adminInfo['aid'],
                'type' => 1,
                'live_id' => $this->liveInfo['live_id'],
                'content' => $content,
                'create_time' => $this->request->time(),
            ];
            $messageId = (new LiveMessageModel())->insertMessage($newRecordId, $insertData, 0);
            LiveMessage::sendMsg(['type' => 'all', 'live_id' => $this->liveInfo['live_id'], 'id' => $this->liveInfo['live_id'], 'uid' => 0], LiveMessage::MSG_TYPE_POP_MSG, [
                'user_info' => null,
                'msg_info' => [
                    'color' => '#FFFFFF',
                    'content' => $content,
                    'id' => $messageId
                ]
            ]);
        }
        return show(config('code.success'), '发送成功');
    }

    /**
     * 获取直播间所有商品
     * @return Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function goodsList()
    {
        $type = input('type/d', 0);
        $gids = (new LiveGoodsActivity())->where('type', $type)->order('id', 'DESC')->column('id');
        $ancho = (new LiveAnchorInfo())->getInfoById($this->liveInfo['live_id'], ['gids']);
        $anchGids = explode(',', $ancho['gids']);
        $resGids = array_intersect($gids, $anchGids);
        $goods = (new LiveGoodsActivity())->batchGetInfoByIds($gids);
        $res = [];
        $mallGoodsAttrModel = new MallGoodsAttr();
        foreach ($goods as $good)
        {
            if ($good['status'] == 1)
            {
                $tmp = [
                    'id' => $good['id'],
                    'img' => $good['img'],
                    'title' => $good['name'],
                    'desc' => $good['des'],
                    'or_price' => '',
                    'now_price' => '',
                    'price_desc' => ''
                ];
                if ($type === 1)
                {
                    if ($good['attr'] != 1)
                    {
                        $discount = (new Util())->numberChinese($good['attr'] * 10);
                        $tmp['price_desc'] = "特惠{$discount}折";
                    } else
                    {
                        $tmp['price_desc'] = '原价';
                    }
                } elseif ($type === 2)
                {
                    $explode = explode(',', $good['gids']);
                    sort($explode);
                    $gid = current($explode);
                    if ($good['category'] == 2)
                    {
                        $mallGood = $mallGoodsAttrModel->batGetInfo([$gid], ['now_price']);
                        $tmp['or_price'] = current($mallGood)['now_price'];
                    }
                    $tmp['now_price'] = $good['attr'];
                }
                if (in_array($good['id'], $resGids, false))
                {
                    $tmp['status'] = 1;
                } else
                {
                    $tmp['status'] = 0;
                }
                $res[] = $tmp;
            }
        }
        array_multisort(array_column($res, 'status'), SORT_NUMERIC, SORT_DESC, $res);// 按 id 排序
        return show(config('code.success'), '请求成功', $res);
    }

    /**
     * 修改当前主播商品权限
     * @return Json
     * @throws \Exception
     */
    public function alterGoodsAuth()
    {
        $gid = input('id/d', 0);
        $anchorModel = new LiveAnchorInfo();
        $ancho = $anchorModel->getInfoById($this->liveInfo['live_id'], ['gids']);
        $anchoGids = explode(',', $ancho['gids']);
        if (in_array($gid, $anchoGids, false))
        {
            //下架
            $key = array_search($gid, $anchoGids);
            array_splice($anchoGids, $key, 1);
            $status = 0;
        } else
        {
            //上架
            $p = array_push($anchoGids, $gid);
            $status = 1;
        }
        $adminInfo = $this->getUserAuth();
        $res = $anchorModel->updateData($this->liveInfo['live_id'], ['gids' => implode(',', $anchoGids), 'aid' => $adminInfo['aid'], 'admin_type' => $adminInfo['admin_type']]);
        if ($res === true)
        {
            return show(config('code.success'), '修改成功', ['status' => $status]);
        }
        return show(config('code.error'), '修改失败');
    }

    /**
     * 获取直播间所有卡券
     * @return Json
     * @throws \think\exception\DbException
     */
    public function couponList()
    {
        $type = input('type/d', 0);
        $couponIdsInfo = (new LiveCoupon())
            ->order('id', 'DESC')
            ->column('id');
        $data = [];
        if ($couponIdsInfo)
        {
            $ancho = (new LiveAnchorInfo())->getInfoById($this->liveInfo['live_id'], ['cids']);
            $anchCids = explode(',', $ancho['cids']);
            $resGids = array_intersect($couponIdsInfo, $anchCids);
            $couponInfo = (new LiveCoupon())->batchGetInfoByIds($couponIdsInfo);
            foreach ($couponIdsInfo as $key => $coupon)
            {
                if ($couponInfo[$coupon]['status'] == 1)
                {
                    if ($couponInfo[$coupon]['type'] == $type)
                    {
                        if (in_array($coupon, $resGids, false))
                        {
                            $status = 1;
                        } else
                        {
                            $status = 0;
                        }
                        $data[] = [
                            'id' => $couponInfo[$coupon]['id'],
                            'img' => $couponInfo[$coupon]['img'],
                            'title' => $couponInfo[$coupon]['lcname'],
                            'desc' => $couponInfo[$coupon]['name'],
                            'status' => $status,
                        ];
                    }
                }
            }
            array_multisort(array_column($data, 'status'), SORT_NUMERIC, SORT_DESC, $data);// 按 id 排序
        }
        return show(config('code.success'), '请求成功', $data);
    }

    /**
     * 修改当前主播卡券权限
     * @return Json
     * @throws \Exception
     */
    public function alterCouponAuth()
    {
        $gid = input('id/d', 0);
        $anchorModel = new LiveAnchorInfo();
        $ancho = $anchorModel->getInfoById($this->liveInfo['live_id'], ['cids']);
        $anchoCids = explode(',', $ancho['cids']);
        if (in_array($gid, $anchoCids, false))
        {
            //下架
            $key = array_search($gid, $anchoCids);
            array_splice($anchoCids, $key, 1);
            $status = 0;
        } else
        {
            //上架
            $p = array_push($anchoCids, $gid);
            $status = 1;
        }
        $adminInfo = $this->getUserAuth();
        $res = $anchorModel->updateData($this->liveInfo['live_id'], ['cids' => implode(',', $anchoCids), 'aid' => $adminInfo['aid'], 'admin_type' => $adminInfo['admin_type']]);
        if ($res === true)
        {
            return show(config('code.success'), '修改成功', ['status' => $status]);
        }
        return show(config('code.error'), '修改失败');
    }

    /**
     * 获取直播间所有卡券
     * @return Json
     * @throws \think\exception\DbException
     */
    public function prizeList()
    {
        $type = input('type/d', 0);
        $prizeIdsInfo = (new LiveAward())
            ->where('type', $type)
            ->order('id', 'DESC')
            ->column('id');
        $data = [];
        if ($prizeIdsInfo)
        {
            $ancho = (new LiveAnchorInfo())->getInfoById($this->liveInfo['live_id'], ['pids']);
            $anchPids = explode(',', $ancho['pids']);
            $resGids = array_intersect($prizeIdsInfo, $anchPids);
            $prizeInfo = (new LiveAward())->batchGetInfoByIds($prizeIdsInfo);
            foreach ($prizeIdsInfo as $key => $prize)
            {
                if ($prizeInfo[$prize]['status'] == 1)
                {
                    if (in_array($prize, $resGids, false))
                    {
                        $status = 1;
                    } else
                    {
                        $status = 0;
                    }
                    $data[] = [
                        'id' => $prizeInfo[$prize]['id'],
                        'title' => $prizeInfo[$prize]['award_name'],
                        'desc' => $prizeInfo[$prize]['award_desc'],
                        'status' => $status,
                    ];
                }
            }
            array_multisort(array_column($data, 'status'), SORT_NUMERIC, SORT_DESC, $data);// 按 id 排序
        }
        return show(config('code.success'), '请求成功', $data);
    }

    /**
     * 修改当前主播抽奖权限
     * @return Json
     * @throws \Exception
     */
    public function alterPrizeAuth()
    {
        $gid = input('id/d', 0);
        $anchorModel = new LiveAnchorInfo();
        $ancho = $anchorModel->getInfoById($this->liveInfo['live_id'], ['pids']);
        $anchoPids = explode(',', $ancho['pids']);
        if (in_array($gid, $anchoPids, false))
        {
            //下架
            $key = array_search($gid, $anchoPids);
            array_splice($anchoPids, $key, 1);
            $status = 0;
        } else
        {
            //上架
            $p = array_push($anchoPids, $gid);
            $status = 1;
        }
        $adminInfo = $this->getUserAuth();
        $res = $anchorModel->updateData($this->liveInfo['live_id'], ['pids' => implode(',', $anchoPids), 'aid' => $adminInfo['aid'], 'admin_type' => $adminInfo['admin_type']]);
        if ($res === true)
        {
            return show(config('code.success'), '修改成功', ['status' => $status]);
        }
        return show(config('code.error'), '修改失败');
    }
}
